#include "bridge.h"
#include "DetourAlloc.h"
#include <new>
#include "DetourLog.h"
#include "DetourCommon.h"

RECAST_API Race* AllocRaceLogic()
{
	void* mem = dtAlloc(sizeof(Race), DT_ALLOC_PERM);
	if (!mem) return 0;
	return new(mem) Race;
}

RECAST_API void FreeRaceLogic(Race* ptr)
{
	if (!ptr) return;
	ptr->~Race();
	dtFree(ptr);
}

RECAST_API void UpdateRaceLogic(Race* ptr,FPRaw dt)
{
	if (!ptr) return;
	ptr->update(dt);
}

RECAST_API bool LoadGeomForRace(Race* ptr, unsigned char* buf, int length)
{
	if (ptr && ptr->load_mesh(buf, length))
	{
		return true;
	}
	return false;
}

RECAST_API bool LoadGeomSettingForRace(Race* ptr, unsigned char* buf, int length)
{
	if (ptr && ptr->load_geom_setting(buf, length))
	{
		return true;
	}
	return false;
}

RECAST_API bool LoadNavMeshForRace(Race* ptr, unsigned char* buf, int length)
{
	if (ptr && ptr->load_navmesh_from_buffer(buf, length))
	{
		return true;
	}
	return false;
}

RECAST_API void GetAgentPos(Race* ptr, int idx, FPRaw* pos)
{
	if (!ptr)
	{
		return;
	}
	fixed64 p[3];
	ptr->getAgentPos(idx, p);
	pos[0] = p[0];
	pos[1] = p[1];
	pos[2] = p[2];
}

RECAST_API int AddAgent(Race* ptr, FPRaw* pos)
{
	if (!ptr)
	{
		return -1;
	}
    fixed64 p[3];
	p[0] = pos[0];
	p[1] = pos[1];
	p[2] = pos[2];
	return ptr->addAgent(p);
}

RECAST_API bool InitCrowd(Race* ptr, const int maxAgents, FPRaw maxAgentRadius)
{
	if (!ptr)
	{
		return false;
	}
	fixed64 maxR = maxAgentRadius;
	return ptr->initCrowd(maxAgents, maxR);
}

RECAST_API bool RandPos(Race* ptr, FPRaw* pos)
{
	if (!ptr)
	{
		return false;
	}
	fixed64 p[3];
	bool v =ptr->randomPos(p);
	dtVcopy(pos, p);
	return v;
}

RECAST_API void RemoveAgent(Race* ptr, const int idx)
{
	if (!ptr)
	{
		return;
	}
	ptr->removeAgent(idx);
}

RECAST_API bool AgentMovePos(Race* ptr, const int idx, FPRaw* targetPos)
{
	if (!ptr)
	{
		return false;
	}
	fixed64 p[3];
	p[0] = targetPos[0];
	p[1] = targetPos[1];
	p[2] = targetPos[2];
	return ptr->agentMovePos(idx, p);
}

RECAST_API bool AgentMoveVelocity(Race* ptr, const int idx, FPRaw* vel)
{
	if (!ptr)
	{
		return false;
	}
	fixed64 p[3];
	p[0] = vel[0];
	p[1] = vel[1];
	p[2] = vel[2];
	return ptr->agentMoveVelocity(idx, p);
}

RECAST_API bool AddTempObstacle(Race* ptr, FPRaw radius, FPRaw height, FPRaw* pos, int* ref)
{
	if (!ptr)
	{
		return false;
	}
	fixed64 p[3];
	p[0] = pos[0];
	p[1] = pos[1];
	p[2] = pos[2];
	return ptr->addTempObstacle(radius, height, p, ref);
}

RECAST_API bool RemoveTempObstacle(Race* ptr, int ref)
{
	if (!ptr)
	{
		return false;
	}
	return ptr->removeTempObstacle(ref);
}

RECAST_API bool StopAgentMove(Race* ptr, int idx)
{
	if (!ptr)
	{
		return false;
	}
	return ptr->stopAgentMove(idx);
}

RECAST_API bool SetAgentPos(Race* ptr, int idx, FPRaw* pos)
{
	if (!ptr)
	{
		return false;
	}
	fixed64 p[3];
	p[0] = pos[0];
	p[1] = pos[1];
	p[2] = pos[2];
	return ptr->setAgentPos(idx, p);
}

